<?php
/**
 * @desc application class file,this is entry for app
 * @author nana
 * @date 2011
 *
 */
require_once(dirname(__FILE__).DIRECTORY_SEPARATOR."global.inc.php");
require_once(DIR_CORE.'bootstrap.php');
class NICED_Application 
{
	public static $controller;
    public static $container;
    protected static $instance;
	
    public static function getInstance()
    {
        if (!self::$instance)
        {
            self::$instance = new NICED_Application();
        }

        return self::$instance;
    }

    public static function init()
    {
        $bootstrap = NICED_Bootstrap::getInstance();
        $bootstrap->init();
        self::$container = new NICED_Container();
        NICED_TIME_STOP("application", "end_init");
    }


	/**
	 * @desc application enter
	 * @todo error page
	 */
	public static function execute($request_name = NULL) 
	{
		try 
		{
            self::init();

            if (!$request_name)
            {
			    $request      = NICED_Request::getInstance();
                $request_name = $request->getRequestName();
            }
            else
            {
                $request      = new NICED_Request($request_name);
                $request_name = $request->getRequestName();
            }

			while (true)
			{
				$controller = self::getController($request_name, self::$container);

				if (method_exists($controller, 'forward'))
				{
					$request_name = $controller->forward();
					continue;
				}
				
                self::dispatch($controller);//$controller->execute();
				break;
			}

		} 
		catch (Exception $e) 
		{
			$controller    = new NICED_Controller();
			$die_view_name = $controller->getMessageDieViewName();
			$view          = $controller->instantiate($die_view_name, 'view', $controller);
			$view->set('exception', $e);
			$view->execute();
		}

        NICED_TIME_STOP("application");
	}

    public static function forward($request_name)
    {
        if (!$request_name)
        {
            throw new NICED_Exception("no request name for relocate");
        }

        self::execute($request_name);
    }

    public static function dispatch($controller)
    {
		$request_name = $controller->getRequestName();
        
        $controller->execute();

        $action_name  = $controller->selectAction();
        //call action's execute method
        $action = $controller->instantiate($action_name, 'action', $controller);
        if ($action instanceof NICED_Action)
        {
            $result = $action->execute();
        }
        else 
        {
            throw new NICED_NotExistsException('instantiate action fail', $action_name);
        }

        $method_name = $controller->buildSelectViewName();

        if (!$method_name) 
        {
            throw new NICED_NotExistsException('build select view method name fail! method name is null');
        }
		
		$view_name   = $controller->$method_name($result);

        if (!$view_name) 
        {
            throw new NICED_NotExistsException('instantiate view fail! view name is null');
        }

        $view = $controller->instantiate($view_name, 'view', $controller);

        if ($view instanceof NICED_View) 
        {
            $view->execute();
        } 
        else 
        {
            throw new NICED_NotExistsException('instantiate view '.$view_name.' fail!');
        }
    }


    public static function getController($request_name, $container = null) 
	{
        self::$controller = NICED_Controller::instantiate($request_name, 'controller', $container);

		return self::$controller;

		try
		{
            self::$controller = NICED_Controller::instantiate($request_name, 'controller', $container);
		}
		catch(Exception $e)
		{
			
		}

		if (!self::$controller)
		{
			self::$controller = self::retrieveController($request_name, $container);
		}

		if (!self::$controller)
		{
			throw new NICED_NotExistsException('create controller '.$request_name.' fail');
		}

		return self::$controller;
	}



	public function __destruct()
	{
		unset(self::$controller);
		unset(self::$container);
	}

}//end class
